home *** CD-ROM | disk | FTP | other *** search
- program wumpus;
-
- const
- maxrooms = 20;
- maxbats = 2;
- maxpits = 2;
- numberofarrows = 7;
- prompt = '> ';
- tunnelsperroom = 2;
- move = 'M';
- quit = 'Q';
- shoot = 'S';
- help = '?';
-
- type
- room = 1..maxrooms;
- rooms = set of room;
-
- var
- cave : array[room] of rooms;
- player : room;
- wumpus : room;
- arrowsleft : integer;
- quitting : boolean;
- killed : boolean;
- wumpuskilled : boolean;
- bats : rooms;
- pits : rooms;
- commandset : set of char;
-
- (*
- * rand
- * returns a random number between low and high
- *)
-
- function rand(low, high : integer) : integer;
-
- begin
- rand := low + random(high-low+1);
- end;
-
- procedure doinstr;
-
- begin
- writeln;
- writeln('Your mission, should you desire to accept it, is it hunt for the');
- writeln('Wumpus in his cave. To succeed, you must shoot it with one of your');
- writeln(numberofarrows:1,' arrows. If you shoot into a room which is not directly connected to');
- writeln('yours, the arrow will bounce to one of the rooms that does connect.');
- writeln('The bats in the cave may pick you up and place you in a different');
- writeln('room. If you enter a room which has a pit, you will fall into it.');
- writeln('If the wumpus finds you or you run out of arrows, you lose.');
- writeln;
- end;
-
- procedure askinstruct;
-
- var
- answer : char;
-
- begin
- write('Do you want instructions? ');
- readln(answer);
- while (answer <> 'y') and (answer <> 'Y') and (answer <> 'n') and (answer <> 'N') do
- begin
- writeln('Please answer yes or no');
- write('Would you like instructions? ');
- readln(answer);
- end;
- if (answer = 'y') or (answer = 'Y') then
- doinstr;
- end;
-
- (*
- * addtunnel
- * make a tunnel connection between two rooms
- *)
-
- procedure addtunnel(from, dest : room);
-
- begin
- cave[from] := cave[from] + [dest];
- cave[dest] := cave[dest] + [from];
- end;
-
- (*
- * makemaze
- * makes a reasonably random maze. for each room tries to make 3 new tunnels.
- * if a tunnel already exists in that direction, another digging that way is
- * not made.
- *)
-
- procedure makemaze;
-
- var
- currentroom, tunnelto, newtunnel : room;
-
- begin
- for currentroom := 2 to maxrooms do
- addtunnel(currentroom, currentroom-1);
- for currentroom := 3 to maxrooms do
- begin
- newtunnel := rand(1, currentroom-1);
- if not newtunnel in cave[currentroom] then
- addtunnel(currentroom, newtunnel);
- end;
- end;
-
- (*
- * skipblanks
- * skips spaces, tabs until eoln
- *)
-
- procedure skipblanks;
-
-
- begin
- end;
-
- (*
- * describe
- * give a description of the current room ( player ). tell player if the
- * wumpus is nearby.
- *)
-
- procedure describe;
-
- var
- i : room;
-
- begin
- writeln('You are in room ',player:1);
- write('There are tunnels leading to rooms');
- for i := 1 to maxrooms do
- if i in cave[player] then
- write(' ',i:1);
- writeln;
- if (player in cave[wumpus]) or ((cave[player] * cave[wumpus]) <> []) then
- writeln('I smell a Wumpus.');
- if cave[player] * bats <> [] then
- writeln('I hear bats.');
- if cave[player] * pits <> [] then
- writeln('I feel a draft.');
- end;
-
- (*
- * command
- * returns the single character that signifies what is to be done
- *)
-
- function command : char;
-
- var
- ch : char;
-
- begin
- describe;
- repeat
- write(prompt);
- readln(ch);
- if not (ch in commandset) then
- begin
- writeln(' Type ? for instructions.');
- end;
- until ch in commandset;
- command := ch;
- end;
-
- (*
- * checkwump
- * move the wumpus and see if it went to the same room as the player,
- * if so he's dead.
- *)
-
- procedure checkwump;
-
- var
- newwumproom : room;
-
- begin
- newwumproom := rand(1, maxrooms);
- if (newwumproom in cave[wumpus]) then
- wumpus := newwumproom;
- if (wumpus = player) then
- begin
- writeln('Look Out!! The Wumpus got you.');
- writeln('Better luck next time.');
- killed := true;
- end;
- end;
-
- (*
- * checkbats
- * if the player is in a room with bats they will pick him up and move him to
- * another room (which will not have bats in it).
- *)
-
- procedure checkbats;
-
- var
- flewto : room;
-
- begin
- if player in bats then
- begin
- repeat
- flewto := rand(1,maxrooms)
- until (not (flewto in (bats + pits))) and (flewto <> wumpus);
- writeln('A superbat picked you up and carried you off.');
- player := flewto;
- end;
- end;
-
- (*
- * checkpits
- * determines if the player fell into a pit.
- *)
-
- procedure checkpits;
-
- begin
- if not killed and (player in pits) then
- begin
- writeln('Don''t do that!! Too late, you fell into a pit.');
- writeln('You should be more careful.');
- killed := true;
- end;
- end;
-
- (*
- * randroom
- * returns a random room number in the range limited by the set argument.
- *)
-
- function randroom ( limitedto : rooms) : integer;
-
- var
- apossibility : room;
-
- begin
- repeat
- apossibility := rand(1, maxrooms);
- until apossibility in limitedto;
- randroom := apossibility;
- end;
-
- (*
- * doshoot
- * player tries to shoot the wumpus by listing the rooms that he wants to
- * shoot through. if the rooms do not match the list, the arrow bounces
- * randomly to a connecting tunnel.
- *)
-
- procedure doshoot;
-
- var
- nextroom, lastroom : room;
-
- begin
- lastroom := player;
- while not eoln do
- begin
- write('where ');
- readln(nextroom);
- if wumpus = nextroom then
- wumpuskilled := true
- else if player = nextroom then
- killed := true;
- if not (nextroom in cave[lastroom]) then
- nextroom := randroom(cave[lastroom]);
- lastroom := nextroom;
- skipblanks;
- end;
- arrowsleft := arrowsleft - 1;
- if killed then
- writeln('You klutz! You just shot yourself.')
- else if wumpuskilled then
- writeln('Congratulations! You slew the fearsome Wumpus.')
- else if arrowsleft = 0 then
- writeln('You ran out of arrows.')
- end;
-
- (*
- * domove
- * player's move, must be to an adjacent room
- *)
-
- procedure domove;
-
- var
- dest : room;
-
- begin
- write('To ');
- readln(dest);
- if not (dest in [1..maxrooms]) then
- writeln('There is no room # ', dest)
- else if not (dest in cave[player]) then
- writeln('I see no tunnel to room # ',dest)
- else
- player := dest;
- checkbats;
- checkwump;
- checkpits;
- end;
-
- (*
- * doquit
- * asks if the player really wants to quit
- *)
-
- procedure doquit;
-
- var
- answer : char;
-
- begin
- writeln;
- write('Do you really want to quit now? ');
- readln(answer);
- quitting := answer in ['y','Y'];
- end;
-
- procedure doaturn(action : char);
-
- begin
- case action of
- move : domove;
- shoot : doshoot;
- quit : doquit;
- help : doinstr;
- end;
- end;
-
- (*
- * gameover
- * returns true if the game is over
- *)
-
- function gameover : boolean;
-
- begin
- gameover := quitting or killed or wumpuskilled or (arrowsleft = 0);
- end;
-
- (*
- * initialize
- * generates a random maze and the positions of the player, wumpus,and bats.
- * make sure that the player doesn't start with the wumpus.
- *)
-
- procedure initialize;
-
- var
- i : room;
-
- begin
- randomize;
- for i := 1 to maxrooms do
- cave[i] := [];
- bats := [];
- pits := [];
- makemaze;
- wumpus := rand(1, maxrooms);
- for i := 1 to maxbats do
- bats := bats + [rand(1, maxrooms)];
- for i := 1 to maxpits do
- pits := pits + [rand(1, maxrooms)];
- repeat
- player := rand(1, maxrooms);
- until (player <> wumpus) and not (player in pits) and not (player in bats);
- quitting := false;
- killed := false;
- wumpuskilled := false;
- arrowsleft := numberofarrows;
- commandset := [move, shoot, quit, help];
- end;
-
- begin
- writeln('Welcome to Wumpus!!');
- askinstruct;
- initialize;
- repeat
- doaturn(command);
- until gameover;
- end.
-
-
-